package pl.edu.uj.tcs.blef.server;

import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map.Entry;

import pl.edu.uj.tcs.blef.protocol.CreateTableRequest;
import pl.edu.uj.tcs.blef.protocol.CreateTableRequestFactory;
import pl.edu.uj.tcs.blef.protocol.CreateTableRequestHandler;
import pl.edu.uj.tcs.blef.protocol.IdentifyRequestFactory;
import pl.edu.uj.tcs.blef.protocol.IdentifyRequestHandler;
import pl.edu.uj.tcs.blef.protocol.NullRequestHandler;
import pl.edu.uj.tcs.blef.protocol.Request;
import pl.edu.uj.tcs.blef.protocol.RequestFactory;
import pl.edu.uj.tcs.blef.protocol.RequestHandler;
import pl.edu.uj.tcs.blef.protocol.ShowTablesRequestFactory;
import pl.edu.uj.tcs.blef.protocol.ShowTablesRequestHandler;
import pl.edu.uj.tcs.blef.protocol.UnknownRequestErrorFactory;

public final class ServerRequestHeadquarters {
	private static HashMap<RequestFactory, RequestHandler> factories;
	private static NullRequestHandler nullRequestHandler;
	private static UnknownRequestErrorFactory unknownRequestErrorFactory;
	
	public ServerRequestHeadquarters(){
		/* Error request factories */
		nullRequestHandler = new NullRequestHandler();
		unknownRequestErrorFactory = new UnknownRequestErrorFactory();
		
		/* Accepted request factories */
		factories = new HashMap<RequestFactory, RequestHandler>();
		factories.put(new IdentifyRequestFactory(), new IdentifyRequestHandler());
		factories.put(new CreateTableRequestFactory(), new CreateTableRequestHandler());
		factories.put(new ShowTablesRequestFactory(), new ShowTablesRequestHandler());
	}
	
	static void parse(String message, Socket socket){
		for(Entry<RequestFactory, RequestHandler> e : factories.entrySet()){
			try { 
				Request request = e.getKey().parse(message, e.getValue());
				System.out.println("Accepted SERVER:" + socket.getLocalPort() + " request: " + message);
				request.getHandler().handle(request, socket);
				return;
			} catch(Exception ex){ }
		}
		
		/* Unknown request */
		try{
			Request unknownRequest = unknownRequestErrorFactory.build(null, nullRequestHandler);
			unknownRequest.send(new PrintWriter(socket.getOutputStream()));
		} catch (Exception e){ return; }
	}
}
